// #include <iostream>
// #include <iomanip>
// using namespace std;
// const int N = 1e9;
// int arr[N][N];
// int memo[N][N];
// int n, m, x, y;
// int dx[] = {0, 1, 0, -1}; // 右、下、左、上
// int dy[] = {1, 0, -1, 0};
// void dfs(int x, int y)
// {
//     for (int i = 0; i < 4; i++)
//     {
//         int a = x + dx[i];
//         int b = y + dy[i];
//         if (memo[N][N])
//             continue;
//         if (a < 0 || a >= n || b < 0 || b >= m)
//             continue;
//     }
// }
// int main()
// {
//     ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//     cin >> n >> m >> x >> y;
//     dfs(x, y);
//     for (int i = 0; i < n; i++)
//     {
//         for (int j = 0; j < m; j++)
//         {
//             cout << memo[i][j] << endl;
//         }
//     }
//         return 0;
// }

// #include <iostream>
// #include <queue>
// #include <iomanip>
// #include <cstring>
// using namespace std;

// const int MAX = 405;
// int dist[MAX][MAX]; // 存储到达每个点的最短步数
// int n, m, x, y;

// // 马的8个移动方向（日字形）
// int dx[] = {2, 1, -1, -2, -2, -1, 1, 2};
// int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};

// void bfs(int startX, int startY)
// {
//     queue<pair<int, int>> q;
//     memset(dist, -1, sizeof(dist)); // 初始化为-1表示未访问

//     startX--; // 题目输入是1-based坐标
//     startY--; // 转换为0-based坐标
//     dist[startX][startY] = 0;
//     q.push({startX, startY});

//     while (!q.empty())
//     {
//         auto [x, y] = q.front();
//         q.pop();

//         for (int i = 0; i < 8; i++)
//         {
//             int nx = x + dx[i];
//             int ny = y + dy[i];

//             // 检查新坐标是否合法
//             if (nx >= 0 && nx < n && ny >= 0 && ny < m)
//             {
//                 // 如果该点未被访问过
//                 if (dist[nx][ny] == -1)
//                 {
//                     dist[nx][ny] = dist[x][y] + 1;
//                     q.push({nx, ny});
//                 }
//             }
//         }
//     }
// }

// int main()
// {
//     ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//     cin >> n >> m >> x >> y;

//     bfs(x, y);

//     // 输出结果（注意坐标转换）
//     for (int i = 0; i < n; i++)
//     {
//         for (int j = 0; j < m; j++)
//         {
//             // 使用setw(5)保证每个数字占5个字符宽度
//             cout << left << setw(5) << dist[i][j];
//         }
//         cout << "\n"; // 换行
//     }
//     return 0;
// }

#include <iostream>
#include <iomanip>
#include <cstring>
using namespace std;

const int MAX = 405;
int dist[MAX][MAX]; // 存储最小步数
int n, m;
// 马的8个移动方向（日字形）
int dx[] = {2, 1, -1, -2, -2, -1, 1, 2};
int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};

void dfs(int x, int y, int step)
{
    // 越界检查
    if (x < 0 || x >= n || y < 0 || y >= m)
        return;

    // 剪枝：如果当前路径步数不比已有记录更优，则放弃
    if (dist[x][y] != -1 && step >= dist[x][y])
        return;

    dist[x][y] = step; // 更新最小步数

    // 向8个方向递归搜索
    for (int i = 0; i < 8; ++i)
    {
        int nx = x + dx[i];
        int ny = y + dy[i];
        dfs(nx, ny, step + 1);
    }
}

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int startX, startY;
    cin >> n >> m >> startX >> startY;

    // 初始化距离为-1（不可达）
    memset(dist, -1, sizeof(dist));

    // 转换1-based坐标为0-based
    startX--;
    startY--;

    // DFS起点（注意：此方法效率极低，仅用于演示DFS思路）
    dfs(startX, startY, 0);

    // 输出结果
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < m; ++j)
        {
            cout << left << setw(5) << dist[i][j];
        }
        cout << "\n";
    }
    return 0;
}